﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x0200003B RID: 59
	[Serializable]
	public abstract class IKSolver
	{
		// Token: 0x060002B7 RID: 695 RVA: 0x0002667C File Offset: 0x0002487C
		public bool IsValid()
		{
			string empty = string.Empty;
			return this.IsValid(ref empty);
		}

		// Token: 0x060002B8 RID: 696
		public abstract bool IsValid(ref string message);

		// Token: 0x060002B9 RID: 697 RVA: 0x00026698 File Offset: 0x00024898
		public void Initiate(Transform root)
		{
			if (this.OnPreInitiate != null)
			{
				this.OnPreInitiate();
			}
			if (root == null)
			{
				Debug.LogError("Initiating IKSolver with null root Transform.");
			}
			this.root = root;
			this.initiated = false;
			string empty = string.Empty;
			if (!this.IsValid(ref empty))
			{
				Warning.Log(empty, root, false);
				return;
			}
			this.OnInitiate();
			this.StoreDefaultLocalState();
			this.initiated = true;
			this.firstInitiation = false;
			if (this.OnPostInitiate != null)
			{
				this.OnPostInitiate();
			}
		}

		// Token: 0x060002BA RID: 698 RVA: 0x0002672C File Offset: 0x0002492C
		public void Update()
		{
			if (this.OnPreUpdate != null)
			{
				this.OnPreUpdate();
			}
			if (this.firstInitiation)
			{
				this.LogWarning("Trying to update IK solver before initiating it. If you intended to disable the IK component to manage it's updating, use ik.Disable() instead of ik.enabled = false, the latter does not guarantee solver initiation.");
			}
			if (!this.initiated)
			{
				return;
			}
			this.OnUpdate();
			if (this.OnPostUpdate != null)
			{
				this.OnPostUpdate();
			}
		}

		// Token: 0x060002BB RID: 699 RVA: 0x00003E33 File Offset: 0x00002033
		public virtual Vector3 GetIKPosition()
		{
			return this.IKPosition;
		}

		// Token: 0x060002BC RID: 700 RVA: 0x00003E3B File Offset: 0x0000203B
		public void SetIKPosition(Vector3 position)
		{
			this.IKPosition = position;
		}

		// Token: 0x060002BD RID: 701 RVA: 0x00003E44 File Offset: 0x00002044
		public float GetIKPositionWeight()
		{
			return this.IKPositionWeight;
		}

		// Token: 0x060002BE RID: 702 RVA: 0x00003E4C File Offset: 0x0000204C
		public void SetIKPositionWeight(float weight)
		{
			this.IKPositionWeight = Mathf.Clamp(weight, 0f, 1f);
		}

		// Token: 0x060002BF RID: 703 RVA: 0x00003E64 File Offset: 0x00002064
		public Transform GetRoot()
		{
			return this.root;
		}

		// Token: 0x1700002B RID: 43
		// (get) Token: 0x060002C0 RID: 704 RVA: 0x00003E6C File Offset: 0x0000206C
		// (set) Token: 0x060002C1 RID: 705 RVA: 0x00003E74 File Offset: 0x00002074
		public bool initiated { get; set; }

		// Token: 0x060002C2 RID: 706
		public abstract IKSolver.Point[] GetPoints();

		// Token: 0x060002C3 RID: 707
		public abstract IKSolver.Point GetPoint(Transform transform);

		// Token: 0x060002C4 RID: 708
		public abstract void FixTransforms();

		// Token: 0x060002C5 RID: 709
		public abstract void StoreDefaultLocalState();

		// Token: 0x060002C6 RID: 710
		public abstract void OnInitiate();

		// Token: 0x060002C7 RID: 711
		public abstract void OnUpdate();

		// Token: 0x060002C8 RID: 712 RVA: 0x00003E7D File Offset: 0x0000207D
		public void LogWarning(string message)
		{
			Warning.Log(message, this.root, true);
		}

		// Token: 0x060002C9 RID: 713 RVA: 0x00026790 File Offset: 0x00024990
		public static Transform ContainsDuplicateBone(IKSolver.Bone[] bones)
		{
			for (int i = 0; i < bones.Length; i++)
			{
				for (int j = 0; j < bones.Length; j++)
				{
					if (i != j && bones[i].transform == bones[j].transform)
					{
						return bones[i].transform;
					}
				}
			}
			return null;
		}

		// Token: 0x060002CA RID: 714 RVA: 0x000267F0 File Offset: 0x000249F0
		public static bool HierarchyIsValid(IKSolver.Bone[] bones)
		{
			for (int i = 1; i < bones.Length; i++)
			{
				if (!Hierarchy.IsAncestor(bones[i].transform, bones[i - 1].transform))
				{
					return false;
				}
			}
			return true;
		}

		// Token: 0x040001D5 RID: 469
		[HideInInspector]
		public Vector3 IKPosition;

		// Token: 0x040001D6 RID: 470
		[Range(0f, 1f)]
		public float IKPositionWeight = 1f;

		// Token: 0x040001D7 RID: 471
		public IKSolver.UpdateDelegate OnPreInitiate;

		// Token: 0x040001D8 RID: 472
		public IKSolver.UpdateDelegate OnPostInitiate;

		// Token: 0x040001D9 RID: 473
		public IKSolver.UpdateDelegate OnPreUpdate;

		// Token: 0x040001DA RID: 474
		public IKSolver.UpdateDelegate OnPostUpdate;

		// Token: 0x040001DB RID: 475
		public bool firstInitiation = true;

		// Token: 0x040001DC RID: 476
		[SerializeField]
		public Transform root;

		// Token: 0x0200003C RID: 60
		[Serializable]
		public class Point
		{
			// Token: 0x060002CC RID: 716 RVA: 0x00003EAA File Offset: 0x000020AA
			public void StoreDefaultLocalState()
			{
				this.defaultLocalPosition = this.transform.localPosition;
				this.defaultLocalRotation = this.transform.localRotation;
			}

			// Token: 0x060002CD RID: 717 RVA: 0x00026830 File Offset: 0x00024A30
			public void FixTransform()
			{
				if (this.transform.localPosition != this.defaultLocalPosition)
				{
					this.transform.localPosition = this.defaultLocalPosition;
				}
				if (this.transform.localRotation != this.defaultLocalRotation)
				{
					this.transform.localRotation = this.defaultLocalRotation;
				}
			}

			// Token: 0x040001DE RID: 478
			public Transform transform;

			// Token: 0x040001DF RID: 479
			[Range(0f, 1f)]
			public float weight = 1f;

			// Token: 0x040001E0 RID: 480
			public Vector3 solverPosition;

			// Token: 0x040001E1 RID: 481
			public Quaternion solverRotation = Quaternion.identity;

			// Token: 0x040001E2 RID: 482
			public Vector3 defaultLocalPosition;

			// Token: 0x040001E3 RID: 483
			public Quaternion defaultLocalRotation;
		}

		// Token: 0x0200003D RID: 61
		[Serializable]
		public class Bone : IKSolver.Point
		{
			// Token: 0x060002CE RID: 718 RVA: 0x00003ECE File Offset: 0x000020CE
			public Bone()
			{
			}

			// Token: 0x060002CF RID: 719 RVA: 0x00003EED File Offset: 0x000020ED
			public Bone(Transform transform)
			{
				this.transform = transform;
			}

			// Token: 0x060002D0 RID: 720 RVA: 0x00003F13 File Offset: 0x00002113
			public Bone(Transform transform, float weight)
			{
				this.transform = transform;
				this.weight = weight;
			}

			// Token: 0x1700002C RID: 44
			// (get) Token: 0x060002D1 RID: 721 RVA: 0x00026898 File Offset: 0x00024A98
			// (set) Token: 0x060002D2 RID: 722 RVA: 0x00003F40 File Offset: 0x00002140
			public RotationLimit rotationLimit
			{
				get
				{
					if (!this.isLimited)
					{
						return null;
					}
					if (this._rotationLimit == null)
					{
						this._rotationLimit = this.transform.GetComponent<RotationLimit>();
					}
					this.isLimited = (this._rotationLimit != null);
					return this._rotationLimit;
				}
				set
				{
					this._rotationLimit = value;
					this.isLimited = (value != null);
				}
			}

			// Token: 0x060002D3 RID: 723 RVA: 0x000268EC File Offset: 0x00024AEC
			public void Swing(Vector3 swingTarget, float weight = 1f)
			{
				if (weight <= 0f)
				{
					return;
				}
				Quaternion quaternion = Quaternion.FromToRotation(this.transform.rotation * this.axis, swingTarget - this.transform.position);
				if (weight >= 1f)
				{
					this.transform.rotation = quaternion * this.transform.rotation;
					return;
				}
				this.transform.rotation = Quaternion.Lerp(Quaternion.identity, quaternion, weight) * this.transform.rotation;
			}

			// Token: 0x060002D4 RID: 724 RVA: 0x00026984 File Offset: 0x00024B84
			public void Swing2D(Vector3 swingTarget, float weight = 1f)
			{
				if (weight <= 0f)
				{
					return;
				}
				Vector3 vector = this.transform.rotation * this.axis;
				Vector3 vector2 = swingTarget - this.transform.position;
				float current = Mathf.Atan2(vector.x, vector.y) * 57.29578f;
				float target = Mathf.Atan2(vector2.x, vector2.y) * 57.29578f;
				this.transform.rotation = Quaternion.AngleAxis(Mathf.DeltaAngle(current, target) * weight, Vector3.back) * this.transform.rotation;
			}

			// Token: 0x060002D5 RID: 725 RVA: 0x00026A28 File Offset: 0x00024C28
			public Quaternion GetSolverSwing(Vector3 swingTarget, float weight = 1f)
			{
				if (weight <= 0f)
				{
					return Quaternion.identity;
				}
				Quaternion quaternion = Quaternion.FromToRotation(this.solverRotation * this.axis, swingTarget - this.solverPosition);
				if (weight >= 1f)
				{
					return quaternion;
				}
				return Quaternion.Lerp(Quaternion.identity, quaternion, weight);
			}

			// Token: 0x060002D6 RID: 726 RVA: 0x00003F56 File Offset: 0x00002156
			public void SetToSolverPosition()
			{
				this.transform.position = this.solverPosition;
			}

			// Token: 0x040001E4 RID: 484
			public float length;

			// Token: 0x040001E5 RID: 485
			public Vector3 axis = -Vector3.right;

			// Token: 0x040001E6 RID: 486
			public RotationLimit _rotationLimit;

			// Token: 0x040001E7 RID: 487
			public bool isLimited = true;
		}

		// Token: 0x0200003E RID: 62
		[Serializable]
		public class Node : IKSolver.Point
		{
			// Token: 0x060002D7 RID: 727 RVA: 0x00003F69 File Offset: 0x00002169
			public Node()
			{
			}

			// Token: 0x060002D8 RID: 728 RVA: 0x00003F71 File Offset: 0x00002171
			public Node(Transform transform)
			{
				this.transform = transform;
			}

			// Token: 0x060002D9 RID: 729 RVA: 0x00003F80 File Offset: 0x00002180
			public Node(Transform transform, float weight)
			{
				this.transform = transform;
				this.weight = weight;
			}

			// Token: 0x040001E8 RID: 488
			public float length;

			// Token: 0x040001E9 RID: 489
			public float effectorPositionWeight;

			// Token: 0x040001EA RID: 490
			public float effectorRotationWeight;

			// Token: 0x040001EB RID: 491
			public Vector3 offset;
		}

		// Token: 0x0200003F RID: 63
		// (Invoke) Token: 0x060002DB RID: 731
		public delegate void UpdateDelegate();

		// Token: 0x02000040 RID: 64
		// (Invoke) Token: 0x060002DF RID: 735
		public delegate void IterationDelegate(int i);
	}
}
